package com.cc.dy.api.impl;

import cn.hutool.core.bean.BeanUtil;
import com.cc.dy.api.AbstractApiService;
import com.cc.dy.api.DyPayService;
import com.cc.dy.api.request.pay.*;
import com.cc.dy.api.response.pay.*;
import com.cc.dy.constant.DyApiUrlConstants;
import com.cc.dy.executer.DyService;
import com.cc.dy.util.SignUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * @author chenChao 2023-08-28 10:56
 */
public class DyPayServiceImpl extends AbstractApiService implements DyPayService {

    public DyPayServiceImpl(DyService dyService) {
        super(dyService);
    }

    /**
     * 预下单接口
     * 预下单接口需要保证同一app_id下每笔订单的out_order_no是唯一的。1
     * 同一订单(app_id，out_order_no相同)重复请求需要保持请求参数一致，否则接口会报错拦截。
     *
     * @param request request
     * @return 预下单结果
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        Map<String, Object> objectMap = BeanUtil.beanToMap(request, new HashMap<>(), true, true);
        request.setSign(SignUtil.requestSign(objectMap, dyService.getDyConfig().getSalt()));
        return postWithAccessToken(DyApiUrlConstants.Pay.CREATE_ORDER, request, CreateOrderResponse.class);
    }

    /**
     * 支付结果查询
     * 响应参数里的 cps_info 字段，由于订单归因与佣金计算存在延迟，支付成功后立即查询可能未计算完成，建议开发者在支付成功后分账前进行查询。
     * 沙盒环境使用说明详见担保支付-沙盒环境。
     *
     * @param request request
     * @return 支付结果
     */
    @Override
    public QueryOrderResponse queryOrder(QueryOrderRequest request) {
        Map<String, Object> objectMap = BeanUtil.beanToMap(request, new HashMap<>(), true, true);
        request.setSign(SignUtil.requestSign(objectMap, dyService.getDyConfig().getSalt()));
        return postWithAccessToken(DyApiUrlConstants.Pay.QUERY_ORDER, request, QueryOrderResponse.class);
    }

    /**
     * 发起退款
     * 交易时间超过 1 年的订单无法提交退款。
     * 支付退款支持单笔交易分多次退款，多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。
     * 申请退款总金额不能超过订单金额。
     * 微信渠道每个支付订单的部分退款次数不能超过 50 次，支付宝渠道不能超过 300 次。
     * 申请退款接口的返回仅代表业务的受理情况，具体退款是否成功，需要通过退款查询接口或者退款回调接口获取结果。
     * 银行卡支付的退款 7 天内到账，支付宝支付（余额、银行卡快捷支付等）的退款 3 个工作日内到账，微信支付（余额、银行卡快捷支付等）的退款 7 天内到账。（退款优先原路退，如用户使用尾号为 1234 的招行借记卡付款，则退款至用户尾号为 1234 的招行借记卡）。
     * 沙盒环境使用说明详见担保支付-沙盒环境。
     *
     * @param request request
     * @return 退款
     */
    @Override
    public CreateRefundResponse createRefund(CreateRefundRequest request) {
        Map<String, Object> objectMap = BeanUtil.beanToMap(request, new HashMap<>(), true, true);
        request.setSign(SignUtil.requestSign(objectMap, dyService.getDyConfig().getSalt()));
        return postWithAccessToken(DyApiUrlConstants.Pay.CREATE_REFUND, request, CreateRefundResponse.class);
    }

    /**
     * 开发者/服务商可以通过接口主动查询退款订单状态。
     *
     * @param request request
     * @return QueryRefundResponse
     */
    @Override
    public QueryRefundResponse queryRefund(QueryRefundRequest request) {
        Map<String, Object> objectMap = BeanUtil.beanToMap(request, new HashMap<>(), true, true);
        request.setSign(SignUtil.requestSign(objectMap, dyService.getDyConfig().getSalt()));
        return postWithAccessToken(DyApiUrlConstants.Pay.QUERY_REFUND, request, QueryRefundResponse.class);
    }

    /**
     * 发起退分账
     * 1.分账回退以原分账单为依据，支持多次回退，申请回退总金额不能超过原分账单分给该接收方的金额。
     * 2.对同一个分账接收方最多能发起次数有如下限制：微信对同一个分账接收方最多能发起 20 次分账回退请求，其他渠道无限制。
     * 3.仅可针对分账时的其它分账方进行退分账，不可针对商家收款户进行操作。
     * 4.分账回退的时限：微信分账回退的时限是 180 天，支付宝退分账有效期最长为 12 个月，其他渠道无限制。
     * 5.发起退分账后，已分账的金额都会流转到分账发起方的现金户，无法重新再发起分账。
     *
     * @param request request
     * @return CreateReturnResponse
     */
    @Override
    public CreateReturnResponse createReturn(CreateReturnRequest request) {
        Map<String, Object> objectMap = BeanUtil.beanToMap(request, new HashMap<>(), true, true);
        request.setSign(SignUtil.requestSign(objectMap, dyService.getDyConfig().getSalt()));
        return postWithAccessToken(DyApiUrlConstants.Pay.CREATE_RETURN, request, CreateReturnResponse.class);
    }
}
